/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author Administrator
 */
import java.util.*;

public class Bank {

    public static AbstractQueue<Person>[] queues = new ListBankQueue[4];
    public static Person[] people = new Person[300];
    public static AbstractQueue<Person> outqueue = new ListBankQueue(people.length);
    public static int[] waitTime = new int[4];
    public static int hourprom = 0, countpeopleattend = 0;


    
    public static void main (String[] args) throws QueueOverflow, QueueUnderflow, FullBankException{

        Scanner input = new Scanner(System.in);
        String menu = "-------Menu------" +
                        "\n1: Ver Actrividades"+
                        "\n2: Salir";
        int option, hour;
        boolean exit = false, stop = false, lleno = false;

        for(int i = 0; i < people.length; i++)
            people[i] = new Person(getRandomArrive(),getRandomWait());

        for(int i = 0; i < 4; i++)
            queues[i] = new ListBankQueue(10);

        peopleSort();
        
        for(int i = 0; i < outqueue.size; i++){
            System.out.println(people[i]);
            outqueue.queue(people[i]);
        }

        do{
            System.out.println(menu);
            option = input.nextInt();
            switch(option){
                case 1:{
                    System.out.println("Ingrese la hora que desea ver (1 - 480)");
                    hour = input.nextInt();
                    while((!outqueue.getEmpty())&&(!stop))
                        if(outqueue.peek().getArrive() <= hour)
                            if(!getFullBank())
                                peopleQueue(outqueue.dequeue());
                            else{
                                stop = true;
                                System.out.println("Lo sentimos el banco se cerro por falta de espacio");
                                System.out.println("Se procedera a atender a todos los que estan adentro");
                                lleno = true;
                            }
                        else
                            stop = true;
                    stop = false;
                    if(outqueue.getEmpty() || (lleno)){
                        peopleDequeue(800);
                        setPromTime(getPromTime()/countpeopleattend);
                        System.out.println("Se atendieron en este dia a " + countpeopleattend + " personas");
                        System.out.println("El tiempo promedio que las personas estuvieron en el banco fue de: "+ getPromTime() + "mins.");
                    }
                        
                }break;
                case 2: exit = true;
                break;
                default: System.out.println("Ingrese una opcion correcta");
            }
        }while(!exit);
    }

    public static int getRandomArrive(){
        double n = Math.random()*480 + 1;
        return((int)n);
    }

    public static int getRandomWait(){
        double n = Math.random()*30 + 1;
        return((int)n);
    }

    public static void peopleSort(){
        Person temp;

        for(int i = 0; i < people.length - 1; i++){
            for (int j = i + 1; j < people.length; j++)
                if(people[i].getArrive() > people[j].getArrive()){
                    temp = people[j];
                    people[j] = people[i];
                    people[i] = temp;
                }
        }
    }

    public static String getEvents(int h){
        String s = "";
        return(s);
    }

    public static void peopleQueue(Person p) throws QueueUnderflow, QueueOverflow, FullBankException{
        FullBankException error = new FullBankException("Esta Lleno");

        peopleDequeue(p.getArrive());

        if(getFullBank())
            throw error;
        
        int tempindex = getBestTime();
        p.setWaitQueueTime(getWaitTime(tempindex));
        queues[tempindex].queue(p);
        waitTime[tempindex] = waitTime[tempindex] + p.getWait();
        System.out.println("Entro la persona " + p + "  en la cola "+ tempindex);
    }

    public static void peopleDequeue(int n) throws QueueUnderflow{
        boolean stop = false;

        for(int i = 0; i < 4; i++){
            while(!stop)
                if(!queues[i].getEmpty())
                    if(((queues[i].peek().getWait()) + (queues[i].peek().getArrive() + queues[i].peek().getWaitQueueTime())) < n){
                        setPromTime(getPromTime() + queues[i].peek().getWait());
                        countpeopleattend++;
                        waitTime[i] = waitTime[i] - queues[i].peek().getWait();
                        System.out.println("Salió la persona " + queues[i].dequeue());
                    }
                    else
                        stop = true;
                else
                    stop = true;
            stop = false;
        }
    }

    public static int getBestTime(){
        int btime = 300, indexbtime = -1;

        for (int i = 0; i < 4; i++){
            if(!queues[i].getFull())
                if (getWaitTime(i) < btime){
                    btime = getWaitTime(i);
                    setPromTime(getPromTime() + getWaitTime(i));
                    indexbtime = i;
                }
        }
        return(indexbtime);
    }

    public static boolean getFullBank(){
        int c = 0;
        for (int i = 0; i < queues.length; i++)
            if(queues[i].getFull())
                c++;
        if(c == queues.length)
            return (true);
        return(false);
    }

    public static void setWaitTime(int n, int number){
        waitTime[n] = number;
    }

    public static int getWaitTime(int n){
        return(waitTime[n]);
    }

    public static int getPromTime(){
        return(hourprom);
    }

    public static void setPromTime(int n){
        hourprom = n;
    }
}
